 
package com.zdkj.subway.rca.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.common.core.constant.SecurityConstants;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.ObjectUtils;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.rca.dto.out.SwCkClearingAccountRepportFaceDTO;
import com.zdkj.subway.rca.dto.out.SwCkClearingAccountRepportFaceExcelDTO;
import com.zdkj.subway.rca.entity.SwCkClearingAccountRepportFace;
import com.zdkj.subway.rca.entity.SwCkClearingTransferDiffReason;
import com.zdkj.subway.rca.entity.SwMessage;
import com.zdkj.subway.rca.feign.SubwaySupportService;
import com.zdkj.subway.rca.mapper.SwCkClearingAccountRepportFaceMapper;
import com.zdkj.subway.rca.service.SwCkClearingAccountRepportFaceService;
import com.zdkj.subway.rca.service.SwCkClearingTransferDiffReasonService;
import com.zdkj.subway.rca.util.LocalDateConverter;
import com.zdkj.subway.rca.util.LocalDateTimeConverter;
import com.zdkj.subway.rca.util.MyDateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 人脸电子票应收应付差异统计表
 *
 * @author stw
 * @date 2020-11-10 11:59:02
 */
@Service
public class SwCkClearingAccountRepportFaceServiceImpl extends ServiceImpl<SwCkClearingAccountRepportFaceMapper, SwCkClearingAccountRepportFace> implements SwCkClearingAccountRepportFaceService {
    private static final Logger log = LoggerFactory.getLogger(SwCkClearingAccountRepportFaceServiceImpl.class);

    @Autowired
    private SwCkClearingTransferDiffReasonService swCkClearingTransferDiffReasonService;
    @Autowired
    private SubwaySupportService subwaySupportService;

    //发送待办打开的链接 //TODO
    private static String url = "";
    //接收待办的部门ID //TODO
    private static int deptId = 9;

    @Override
    public List<SwCkClearingAccountRepportFaceDTO> getSwCkClearingAccountRepportFaceList(String startDate, String endDate) {
        return  this.baseMapper.getSwCkClearingAccountRepportFaceList(startDate,endDate,null);
    }

    @Override
    public List<SwCkClearingAccountRepportFaceDTO> setReplayLimitPre(List<Long> ids) {
        List<SwCkClearingAccountRepportFaceDTO> dtos = this.baseMapper.getSwCkClearingAccountRepportFaceList(null,null,ids);
        //获取系统参数配置
        Integer clearingTimeLimit = swCkClearingTransferDiffReasonService.getClearingTimeLimit();
        for(SwCkClearingAccountRepportFaceDTO dto : dtos) {
            if(dto.getReplyLimit() == null){
                dto.setReplyLimit(clearingTimeLimit);
            }
        }
        return  dtos;
    }

    @Override
    public Boolean setReplayLimit(List<SwCkClearingAccountRepportFaceDTO> swCkClearingAccountRepportFaceDTOs) {

        Integer clearingTimeLimit = swCkClearingTransferDiffReasonService.getClearingTimeLimit();
        boolean hasSet = false;
        for(SwCkClearingAccountRepportFaceDTO dto : swCkClearingAccountRepportFaceDTOs){
            if (dto.getReplyLimit()==null) {
                continue;
            } else if(dto.getReplyLimit() > clearingTimeLimit || dto.getReplyLimit() <= 0) { //不能超过系统参数配置
                continue;
            }
            SwCkClearingAccountRepportFace swCkClearingAccountRepportFace = this.getById(dto.getId());
            swCkClearingAccountRepportFace.setReplyLimit(dto.getReplyLimit());
            this.updateById(swCkClearingAccountRepportFace);

            SwCkClearingTransferDiffReason contion = new  SwCkClearingTransferDiffReason();
            contion.setRelationId(dto.getId());
            contion.setDiffSource("3");
            SwCkClearingTransferDiffReason swCkClearingTransferDiffReason = swCkClearingTransferDiffReasonService.getOne(Wrappers.query(contion));
            if(swCkClearingTransferDiffReason != null) {
                swCkClearingTransferDiffReason.setReplayLimit(dto.getReplyLimit());
                swCkClearingTransferDiffReasonService.updateById(swCkClearingTransferDiffReason);
            }
            hasSet = true;
        }
        return hasSet;
    }

    @Override
    public Boolean send(List<Long> ids) {
        List<SwCkClearingAccountRepportFaceDTO> list = this.baseMapper.getSwCkClearingAccountRepportFaceList(null,null,ids);
        PigxUser user = SecurityUtils.getUser();
        String sendDeptCode = swCkClearingTransferDiffReasonService.getDeptCodeById(user.getDeptId());
        boolean hasSend = false;
        //BigDecimal num = new BigDecimal("100");
        for (SwCkClearingAccountRepportFaceDTO dto : list) {
            SwCkClearingTransferDiffReason contion = new  SwCkClearingTransferDiffReason();
            contion.setRelationId(dto.getId());
            contion.setDiffSource("3");
            SwCkClearingTransferDiffReason swCkClearingTransferDiffReason = swCkClearingTransferDiffReasonService.getOne(Wrappers.query(contion));
            if(swCkClearingTransferDiffReason == null) { //为空就新建
                swCkClearingTransferDiffReason = new SwCkClearingTransferDiffReason();
                swCkClearingTransferDiffReason.setRelationId(dto.getId());
                swCkClearingTransferDiffReason.setDiffSource("3");
                swCkClearingTransferDiffReason.setReplayLimit(dto.getReplyLimit());
                swCkClearingTransferDiffReason.setIsReplay(0);
                swCkClearingTransferDiffReason.setSendStatus(1);
                swCkClearingTransferDiffReason.setSendTime(LocalDateTime.now());
                swCkClearingTransferDiffReason.setDeptId(user.getDeptId());
                swCkClearingTransferDiffReason.setCreatorId(user.getId());
                swCkClearingTransferDiffReason.setCreatorName(user.getNikeName());
                swCkClearingTransferDiffReasonService.save(swCkClearingTransferDiffReason);

                //更新本条记录
                SwCkClearingAccountRepportFace swCkClearingAccountRepportFace = this.getById(dto.getId());
                swCkClearingAccountRepportFace.setSendStatus(1);
                swCkClearingAccountRepportFace.setSendTime(LocalDateTime.now());
                this.updateById(swCkClearingAccountRepportFace);

                //通知
                SwMessage swMessage = ObjectUtils.getDefaultObj(SwMessage.class);
                swMessage.setTitle(dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "人脸电子票应收应付差异统计协查");
                swMessage.setContent(dto.getTradeDate().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "差异（ACC-实收）:" + dto.getDiffAccMoney());
                swMessage.setMsgType("差异协查");
                swMessage.setUrl(url);
                swMessage.setSendDeptCode(sendDeptCode);
                swMessage.setDeptId(deptId);
                subwaySupportService.saveInner(swMessage, SecurityConstants.FROM_IN);

            } else { //有了跳过
                continue;
            }
            hasSend = true;
        }

        return hasSend;
    }

    @Override
    public void export(List<Long> ids, HttpServletResponse response) {

        List<SwCkClearingAccountRepportFaceDTO> oldList = this.baseMapper.getSwCkClearingAccountRepportFaceList(null,null,ids);
        //按日期正序
        List<SwCkClearingAccountRepportFaceDTO> newList =
                oldList.stream().sorted(Comparator.comparing(SwCkClearingAccountRepportFaceDTO::getTradeDate)).collect(Collectors.toList());
        List<SwCkClearingAccountRepportFaceExcelDTO> records = new ArrayList<>();
        //BigDecimal num = new BigDecimal("100");
        for(SwCkClearingAccountRepportFaceDTO obj : newList){
            SwCkClearingAccountRepportFaceExcelDTO dto = new SwCkClearingAccountRepportFaceExcelDTO();
            dto.setTradeDateStr(MyDateUtil.LocalDateTurnString(obj.getTradeDate()));
            dto.setTradeDate(obj.getTradeDate());
            dto.setRealIncomeMoney(obj.getRealIncomeMoney());
            dto.setAccMoney(obj.getAccMoney());
            dto.setDiffAccMoney(obj.getDiffAccMoney());
            dto.setIsLimitedReply("1".equals(obj.getIsLimitedReply()) ? "是" : "否");
            dto.setSendStatus(obj.getSendStatus() == 1 ? "是" : "否");
            dto.setDiffReasonTime(obj.getDiffReasonTime());
            dto.setDiffReason(obj.getDiffReason());
            records.add(dto);
        }
        SwCkClearingAccountRepportFaceExcelDTO dto = new SwCkClearingAccountRepportFaceExcelDTO();
        dto.setTradeDateStr("合计");
        BigDecimal realIncomeMoneyTotal = newList.stream().map(SwCkClearingAccountRepportFaceDTO::getRealIncomeMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal accMoneyTotal = newList.stream().map(SwCkClearingAccountRepportFaceDTO::getAccMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal diffAccMoneyTotal = newList.stream().map(SwCkClearingAccountRepportFaceDTO::getDiffAccMoney).reduce(BigDecimal.ZERO, BigDecimal::add);

        dto.setRealIncomeMoney(realIncomeMoneyTotal);
        dto.setAccMoney(accMoneyTotal);
        dto.setDiffAccMoney(diffAccMoneyTotal);
        records.add(dto);
        InputStream excelTemplateIs = null;
        try {response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode("人脸电子票应收应付差异统计表", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
            // {} 代表普通变量 {.} 代表是list的变量

            excelTemplateIs = this.getClass().getResourceAsStream("/static/excel/template/export/SwCkClearingAccountRepportFaceExcelTemplate.xlsx");

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerConverter(new LocalDateTimeConverter()).registerConverter(new LocalDateConverter()).withTemplate(excelTemplateIs).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("人脸电子票应收应付差异统计表").build();
            // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
            // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
            // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
            // 如果数据量大 list不是最后一行 参照另一个
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
            excelWriter.fill(records, fillConfig, writeSheet);

            excelWriter.finish();

        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出人脸电子票应收应付差异统计表异常");
        } finally {
            if(excelTemplateIs != null){
                try {
                    excelTemplateIs.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }

    }
}
